import AlpineInstance from 'alpinejs'
import { clk } from '../clk'
import { clkStore, runtimeConfig } from '../config/runtimeConfig'
import { $, $A, toBinaryStr } from '../utils'
import { edgeConfig } from '../config/edgeConfig'

/**
 * 高亮snapshot中的某一行
 */
function handleHighlightSnapshotRow(e: MouseEvent) {
    let dom = e.target as HTMLElement
    if (!dom.classList.contains('row')) {
        dom = dom.parentElement as HTMLElement
    }
    if (dom.classList.contains('highlight')) {
        dom.classList.remove('highlight')
    } else {
        dom.classList.add('highlight')
    }
}

function initAlpineData() {
    // 控制时钟
    AlpineInstance.data('clk', () => {
        return {
            step: () => clk.step(),
            rise: () => clk.rise(),
            neg: () => clk.neg(),
            run: () => clk.run(),
            stop: () => clk.stop(),
        }
    })
    // 控制数据显示的进制
    AlpineInstance.data('radix', () => {
        return {
            radix: runtimeConfig.dataDisplayRadix,
            init() {
                this.$watch('radix', (newVal: number) => {
                    runtimeConfig.dataDisplayRadix = +newVal
                    $A('.data-item-val').forEach((dom) => {
                        if (!dom.dataset.value) {
                            return
                        }
                        const val = +dom.dataset.value
                        if (!isNaN(val)) {
                            dom.textContent = toBinaryStr(val)
                        }
                    })
                })
            },
        }
    })
    // 记录数据
    AlpineInstance.data('snapshot', () => {
        return {
            ...runtimeConfig.snapshot,
            init() {
                for (const key in runtimeConfig.snapshot) {
                    this.$watch(key, (newVal: boolean) => {
                        runtimeConfig.snapshot[
                            key as keyof typeof runtimeConfig.snapshot
                        ] = newVal
                    })
                }
            },
        }
    })
    // 显示tooltip
    AlpineInstance.data('showTooltip', () => {
        return {
            showTooltip: runtimeConfig.showTooltip,
            init() {
                this.$watch('showTooltip', (newVal: boolean) => {
                    runtimeConfig.showTooltip = newVal
                })
            },
        }
    })
    // 速度调整
    AlpineInstance.data('speed', () => {
        return {
            speed: edgeConfig.speed,
            init() {
                this.$watch('speed', (newVal: number) => {
                    edgeConfig.setSpeed(+newVal)
                })
            },
        }
    })
}

/**
 * 给页面中的元素添加事件
 */
export function initDomListener() {
    // 使用alpinejs
    initAlpineData()

    // logger中的row被点击时高亮或取消高亮
    $('.snapshots-container')?.addEventListener(
        'click',
        handleHighlightSnapshotRow
    )
    // logger中的row被点击时高亮或取消高亮
    $('.snapshots-container')?.addEventListener('wheel', (e) => {
        // 横向滚动
        if (e.deltaY !== 0) {
            e.preventDefault()
            // @ts-ignore
            e.currentTarget.scrollLeft += e.deltaY
            // 如果已经滚动到最左边或最右边，就让父元素接管滚动
            if (
                // @ts-ignore
                e.currentTarget.scrollLeft === 0 ||
                // @ts-ignore
                e.currentTarget.scrollLeft ===
                    // @ts-ignore
                    e.currentTarget.scrollWidth - e.currentTarget.clientWidth
            ) {
                // 让跟元素滚动
                document.documentElement.scrollTop += e.deltaY
            }
        }
    })

    // 设置快捷键，按下n键或者空格键时，执行clk.step()
    document.addEventListener('keypress', (e) => {
        if (!clkStore.isAnimating && e.key.toLowerCase() === 'n' || e.key === ' ') {
            clk.step()
        }
    })
    
}
